package com.ruicar.afs.cloud.afscase.remind.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.afscase.approvetask.entity.CaseApproveRecord;
import com.ruicar.afs.cloud.afscase.approvetask.entity.WorkTaskPool;
import com.ruicar.afs.cloud.afscase.approvetask.service.CaseApproveRecordService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolHistoryService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseBaseInfoService;
import com.ruicar.afs.cloud.afscase.mq.approvesendinfo.service.ApproveInformInfoService;
import com.ruicar.afs.cloud.afscase.processor.enums.NormalSubmitType;
import com.ruicar.afs.cloud.afscase.processor.service.ApproveWorkflowService;
import com.ruicar.afs.cloud.afscase.processor.vo.NormalTaskSubmitVO;
import com.ruicar.afs.cloud.afscase.remind.condition.RemindCondition;
import com.ruicar.afs.cloud.afscase.remind.entity.CaseRemindDetail;
import com.ruicar.afs.cloud.afscase.remind.service.RemindService;
import com.ruicar.afs.cloud.afscase.remind.vo.RemindVo;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.security.service.AfsUser;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Description 留言、提醒
 * @Author Peng_Jinbo
 * @Date 2020/05/30 10:31
 */
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/remind")
public class RemindController {

    private RemindService remindService;

    private CaseApproveRecordService caseApproveRecordService;

    private WorkTaskPoolService workTaskPoolService;

    private WorkTaskPoolHistoryService workTaskPoolHistoryService;

    private ApproveInformInfoService approveInformInfoService;

    private ApproveWorkflowService approveWorkflowService;

    private CaseBaseInfoService caseBaseInfoService;

    /**
     * @Description 保存留言
     * @Author Peng_Jinbo
     * @Date 2020/6/1 10:33
     */
    @PostMapping("/remind")
    @Transactional
    public IResponse createRemind(@RequestParam("remind")String remindJsonStr,
                                  @RequestParam("record")String recordJsonStr,
                                  @RequestParam("remindOprType")String remindOprType){
        AfsUser user = SecurityUtils.getUser();

        String uuid = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
        String once = uuid + System.currentTimeMillis();
        // 审批日志参数
        CaseApproveRecord record = JSONObject.parseObject(recordJsonStr,CaseApproveRecord.class);

        // 1.留言记录信息
        CaseRemindDetail remindDetail = JSONObject.parseObject(remindJsonStr,CaseRemindDetail.class);
        remindDetail.setDisposeUser(user.getUserRealName());
        remindDetail.setDisposeUserId(user.getId().toString());
        remindDetail.setStatus(CancelStatusEnum.EFFECTIVE.getCode());
        remindDetail.setDisposeTime(new Date());
        remindDetail.setUseScene(record.getUseScene());
        remindDetail.setOperationType(remindOprType);
        remindDetail.setMindId(once);
        // 内部留言默认 经销商不可见
        if(RemindTypeEnum.INNER.getValue().equals(remindDetail.getRemindType())){
            remindDetail.setRemindPowers(RemindPowerEnum.UN_VISIBLE.getValue());
        }else{
            remindDetail.setRemindPowers(RemindPowerEnum.VISIBLE.getValue());
        }

        // 公共日志参数
        record.setApplyNo(remindDetail.getApplyNo());
        record.setUseScene(UseSceneEnum.APPROVE.getValue());
        record.setDisposeStaff(user.getUserRealName());
        record.setApproveEndTime(new Date());

        // 2.留言日志
        CaseApproveRecord remindRecord = new CaseApproveRecord();
        BeanUtil.copyProperties(record,remindRecord);

        remindRecord.setApproveType(ApproveTypeEnum.REMIND.getValue());
        remindRecord.setApproveSuggestName(RemindTypeEnum.getNameByValue(remindDetail.getRemindType()));
        remindRecord.setApproveSuggest(remindDetail.getRemindType());
        remindRecord.setApproveReason(remindDetail.getRemindReason());
        remindRecord.setApproveRemark(remindDetail.getRemindContent());
        remindRecord.setMindId(once);


        if(RemindOperateTypeEnum.REJECT.getValue().equals(remindOprType)
            || RemindOperateTypeEnum.PARSE.getValue().equals(remindOprType)){
            WorkTaskPool taskPool = workTaskPoolService.getOne(
                    Wrappers.<WorkTaskPool>lambdaQuery().eq(WorkTaskPool::getStageId, record.getStageId()));

            record.setApproveStartTime(taskPool.getStartTime());

            remindRecord.setDisposeNode(taskPool.getTaskNodeId());
            remindRecord.setDisposeNodeName(taskPool.getTaskNodeName());
            remindRecord.setApproveStartTime(taskPool.getStartTime());

            // 3.流程日志
            CaseApproveRecord approveRecord = new CaseApproveRecord();
            BeanUtil.copyProperties(record,approveRecord);
            approveRecord.setApproveType(ApproveTypeEnum.PROCESS.getValue());
            approveRecord.setApproveSuggestName(RemindOperateTypeEnum.getNameByValue(remindOprType));
            approveRecord.setApproveSuggest(remindOprType);
            approveRecord.setApproveRemark(record.getApproveRemark());
            approveRecord.setApproveStartTime(approveRecord.getApproveEndTime());

            if(RemindOperateTypeEnum.REJECT.getValue().equals(remindOprType)){
                approveRecord.setApproveSuggest(AfsEnumUtil.key(NormalSubmitType.SEND_BACK));
                approveRecord.setApproveSuggestName(AfsEnumUtil.desc(NormalSubmitType.SEND_BACK));
                CaseApproveRecord noticeRecord = new CaseApproveRecord();
                BeanUtil.copyProperties(approveRecord,noticeRecord);
                CaseApproveRecord flowRecord = approveRecord;
                if(JSON.isValid(taskPool.getRemainData())){
                    JSONObject remainData = JSONObject.parseObject(taskPool.getRemainData());
                    String remainRecordKey = AfsEnumUtil.key(RemainKeyEnum.RECORD);
                    if(remainData.containsKey(remainRecordKey) && JSON.isValid(remainData.getString(remainRecordKey))){
                        flowRecord = remainData.getJSONObject(remainRecordKey).toJavaObject(CaseApproveRecord.class);
                        flowRecord.setApproveSuggest(AfsEnumUtil.key(NormalSubmitType.SEND_BACK));
                        flowRecord.setApproveSuggestName(AfsEnumUtil.desc(NormalSubmitType.SEND_BACK));
                        flowRecord.setUseScene(UseSceneEnum.APPROVE.getValue());
                        flowRecord.setApproveType(ApproveTypeEnum.PROCESS.getValue());
                    }
                }
                noticeRecord.setApproveReason(remindDetail.getRemindContent());
                approveWorkflowService.submit(NormalTaskSubmitVO.builder().record(flowRecord).noticeClientRecord(noticeRecord).build());
            }else{
                approveRecord.setApproveSuggest(AfsEnumUtil.key(NormalSubmitType.PARSE));
                approveRecord.setApproveSuggestName(AfsEnumUtil.desc(NormalSubmitType.PARSE));
                approveWorkflowService.submit(NormalTaskSubmitVO.builder().record(approveRecord).build());
            }
        }else if(RemindPowerEnum.VISIBLE.getValue().equals(remindDetail.getRemindPowers())){
            //经我处理任务池中，业务状态为修订-暂停的案件，追加留言通知进件端
            if (AfsEnumUtil.key(BusinessStateInEnum.REVISE_PARSE).equals(record.getBusinessStateIn())) {
                approveInformInfoService.submitDealWithMessage(remindDetail);
            } else {
                // 通知进件系统
                approveInformInfoService.submitLeaveMessage(remindDetail);
            }
        }
        caseApproveRecordService.save(remindRecord);
        remindService.save(remindDetail);
        return IResponse.success("ok");
    }

    /**
     * queryRemindListByApplyNo
     * <p>Description: 根据条件查询留言/提醒列表</p>
     *
     * @param
     * @return
     */
    @PostMapping(value = "/queryRemindListByApplyNo")
    @ApiOperation(value = "根据条件查询留言/提醒列表")
    public IResponse<List<RemindVo>> queryRemindListByApplyNo(@ModelAttribute RemindCondition remindCondition) {
        List<RemindVo> remindVoList = new ArrayList<>();
        List<CaseRemindDetail> caseRemindDetailList =  remindService.list(Wrappers.<CaseRemindDetail>query().lambda()
                .eq(ObjectUtils.isNotEmpty(remindCondition.getApplyNo()),CaseRemindDetail::getApplyNo,remindCondition.getApplyNo())
                .eq(CaseRemindDetail::getStatus,CancelStatusEnum.EFFECTIVE.getCode())
                .eq(ObjectUtils.isNotEmpty(remindCondition.getUseScene()),CaseRemindDetail::getUseScene,remindCondition.getUseScene())
        );
        boolean caseNormalFlowEnd = caseBaseInfoService.checkNormalFlowEnd(remindCondition.getApplyNo(),remindCondition.getStageId());
        if(CollectionUtils.isNotEmpty(caseRemindDetailList)){
            caseRemindDetailList.forEach(caseRemindDetail->{
                RemindVo remindVo = new RemindVo();
                BeanUtils.copyProperties(caseRemindDetail,remindVo);
                /**  撤销操作权限  **/
                if(caseNormalFlowEnd){ // 审批结束后不允许撤销
                    remindVo.setCancel(false);
                }else {
                    String id = SecurityUtils.getUser().getId().toString();
                    if (id.equals(remindVo.getDisposeUserId())) {
                        remindVo.setCancel(true);
                    } else {
                        remindVo.setCancel(false);
                    }
                }
                remindVoList.add(remindVo);
            });
        }
        return IResponse.success(remindVoList);
    }
    /**
     * cancelRemindtById
     * <p>Description: 撤销留言</p>
     *
     * @param
     * @return
     */
    @PostMapping(value = "/cancelRemindtById")
    @ApiOperation(value = "撤销留言")
    @Transactional(rollbackFor = Exception.class)
    public IResponse<List<RemindVo>> cancelRemindtById(@ModelAttribute RemindCondition remindCondition) {
        //删除日志表中的留言记录
        CaseRemindDetail remind = remindService.getOne(Wrappers.<CaseRemindDetail>lambdaQuery()
                .eq(CaseRemindDetail::getId, remindCondition.getRemindId()));
        CaseApproveRecord caseApproveRecord = caseApproveRecordService.getOne(Wrappers.<CaseApproveRecord>lambdaQuery()
                .eq(CaseApproveRecord::getMindId, remind.getMindId()));
        if (ObjectUtils.isNotEmpty(caseApproveRecord)) {
            caseApproveRecordService.removeById(caseApproveRecord);
        }
        //撤销留言表的留言
        if(!StringUtils.isEmpty(remindCondition.getRemindId())){
            remindService.update(Wrappers.<CaseRemindDetail>update().lambda()
                    .eq(CaseRemindDetail::getId,remindCondition.getRemindId())
                    .set(CaseRemindDetail::getStatus,CancelStatusEnum.CANCELED.getCode())
            );
        }
        return IResponse.success("success");
    }

}
